

import bpy


from 全局控制.Node.节点和插座基类.bl_UpdateNode import *
from 对象操作 import bl_对象变换帧

import Core.bl_渲染层 as 渲染层
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类

import 节点.对象操作.bl_物体拷贝 as 物体拷贝

from 节点.全局控制.Node.物体数据生成 import bl_集合物体处理
from 节点.全局控制.Node.节点数据类型 import bl_集合数据类型

from 物体.物体管理 import engine_物体创建

from itertools import chain



import engine.initLIB.load_dll as engineLib
import ctypes


engineLib.flexCAPI.f_创建物体拷贝节点.restype = ctypes.c_bool
















def f_实例拷贝物体(源物体, 集合, 拷贝数量, 是否实例拷贝=True):
	if 是否实例拷贝 :
		data = 源物体.data
	else:
		data = 源物体.data.copy()

	已有物体数量 = len(集合.objects)

	for i in range(拷贝数量):
		if i >= 已有物体数量 : 
			new_object = bpy.data.objects.new(name= 源物体.name+"_物体拷贝"+str(i), object_data=data)
			new_object.scale = 源物体.scale
			new_object.location = 源物体.location
			new_object.rotation_euler = 源物体.rotation_euler
			
			集合.objects.link(new_object)
		else:
			new_object = 集合.objects[i]
			new_object.data = data
		
		new_object.m_物体ID = engine_物体创建.f_添加物体到引擎(new_object, 构建数据=False)
		
	if 拷贝数量 < 已有物体数量:
		for i in range(已有物体数量-拷贝数量):
			要移除的对象 = 集合.objects[-1]
			集合.objects.unlink(要移除的对象)







def f_拷贝物体(源物体, 集合, 拷贝数量, 是否实例拷贝=True, 是否拷贝材质=True):
	已有物体数量 = len(集合.objects)

	for i in range(拷贝数量):
		if 是否实例拷贝 :
			data = 源物体.data
		else:
			data = 源物体.data.copy()



		if i >= 已有物体数量 : 
			new_object = bpy.data.objects.new(name= 源物体.name+"_物体拷贝"+str(i), object_data=data)
			new_object.scale = 源物体.scale
			new_object.location = 源物体.location
			new_object.rotation_euler = 源物体.rotation_euler
			
			集合.objects.link(new_object)
		else:
			new_object = 集合.objects[i]
			new_object.data = data

		#print('是否拷贝材质 = ', 是否拷贝材质)
		if 是否拷贝材质 :
			#print('new_object.material_slots, data.material_slots = ', new_object.material_slots, 源物体.material_slots)
			for mat, s_mat in zip(new_object.material_slots, 源物体.material_slots):
				mat.material = s_mat.material.copy()
				#print('mat.material = ', mat.material, s_mat.material)

		new_object.m_物体ID = engine_物体创建.f_添加物体到引擎(new_object, 构建数据=False)
		
	if 拷贝数量 < 已有物体数量:
		for i in range(已有物体数量-拷贝数量):
			要移除的对象 = 集合.objects[-1]
			集合.objects.unlink(要移除的对象)










def f_多物体拷贝(源物体, 集合, 拷贝数量, 是否实例拷贝=True, 是否拷贝材质=True):
	已有物体数量 = len(集合.objects)

	以拷贝物体数量 = 0
	for i in range(拷贝数量):
		for obj in 源物体:
			if 是否实例拷贝 :
				data = obj.data
			else:
				data = obj.data.copy()

			if 以拷贝物体数量 >= 已有物体数量 : 
				print('f_多物体拷贝 obj = ', obj, data)
				new_object = bpy.data.objects.new(name= obj.name+"_物体拷贝"+str(以拷贝物体数量), object_data=data)
				集合.objects.link(new_object)
			else:
				new_object = 集合.objects[以拷贝物体数量]
				new_object.data = data

			new_object.scale = obj.scale
			new_object.location = obj.location
			new_object.rotation_euler = obj.rotation_euler

			if 是否拷贝材质 :
				#print('new_object.material_slots, data.material_slots = ', new_object.material_slots, 源物体.material_slots)
				for mat, s_mat in zip(new_object.material_slots, obj.material_slots):
					mat.material = s_mat.material.copy()
					#print('mat.material = ', mat.material, s_mat.material)

			以拷贝物体数量 += 1
			#new_object.m_物体ID = engine_物体创建.f_添加物体到引擎(new_object, 构建数据=False)

	if len(源物体) <= 0 :
		for obj in 集合.objects:
			集合.objects.unlink(obj)
	elif 以拷贝物体数量 < 已有物体数量:
		for i in range(已有物体数量-以拷贝物体数量):
			要移除的对象 = 集合.objects[-1]
			集合.objects.unlink(要移除的对象)



def f_多物体数据链接(源物体, 集合, 拷贝数量):
	已有物体数量 = len(集合.objects)

	以拷贝物体数量 = 0
	for i in range(拷贝数量):
		for obj in 源物体:
			data = obj.data
			#print('f_多物体数据链接 = ', len(集合.objects), 以拷贝物体数量)
			new_object = 集合.objects[以拷贝物体数量]
			new_object.data = data

			new_object.scale = obj.scale
			new_object.location = obj.location
			new_object.rotation_euler = obj.rotation_euler
			
			以拷贝物体数量 += 1
			#new_object.m_物体ID = engine_物体创建.f_添加物体到引擎(new_object, 构建数据=False)



def f_update_拷贝物体(self, context):
	if context :
		self.id_data.f_节点数据更新_更新树([self])
#def f_设置拷贝数量update(self, context):
#	pass
class C_拷贝物体节点(基类.C_Node_基类):
	bl_dname = 'bl_node_物体拷贝'
	bl_label = '物体拷贝'
	
	m_是否实例拷贝 = bpy.props.BoolProperty(default=True, name="实例", update=f_update_拷贝物体)
	m_是否拷贝材质 = bpy.props.BoolProperty(default=False)
	m_拷贝父子关系 = bpy.props.BoolProperty(default=True, name="父子关系")
	#m_拷贝数量 = bpy.props.IntProperty(default=1, name='数量:')
	def init(self, context):
		super(C_拷贝物体节点, self).f_init(context)
		self.inputs.new('C_Socket_物体_Array1D', name='物体')
		self.inputs.new('C_Socket_物体_Array1D', name='映射物体')
		self.inputs.new('C_Socket_集合', name='集合')
		self.inputs.new('C_Socket_UI32', name='拷贝数量')
		
		self.outputs.new('C_Socket_物体_Array1D', name='物体集')
		self.f_toCPP(self.id_data)

		#self.inputs['拷贝数量'].f_update()

		
	def draw_buttons(self, context, layout):
		layout.prop(self, 'm_是否实例拷贝')
		layout.prop(self, 'm_拷贝父子关系')
		layout.prop(self, 'm_是否拷贝材质')

	def f_toCPP(self, tree):
		是否更新 = engineLib.flexCAPI.f_创建物体拷贝节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		if 是否更新 :
			self.inputs['拷贝数量'].f_update()

	def f_update(self):
		物体 = self.inputs['物体'].f_getData();
		集合 = self.inputs['集合'].f_getData();
		拷贝数量 = self.inputs['拷贝数量'].f_getData();
		#print('f_update ----拷贝数量------- 新物体 = ', 拷贝数量, 物体)
		
		if 集合 == None :
			name = '__物体拷贝集合_' + self.name
			集合 = bl_集合物体处理.f_get集合(name=name)
			
		
		if 物体 == None:
			for obj in 集合.objects :
				集合.objects.unlink(obj)
				#print('unlink  f_多物体拷贝 = ', 集合, 物体)
		else:
			#print('拷贝数量 == ', 拷贝数量)
			#print("C_拷贝物体节点 = ", self, 集合.objects[0], 物体)
			重新构建 = True
			if len(集合.objects) == 拷贝数量*len(物体) :
				f_多物体数据链接(物体, 集合, 拷贝数量)
				#print('重新构建 = ', 重新构建, len(集合.objects), len(物体))
				#if engineLib.flexCAPI.f_node_是否即时更新节点() and 重新构建:
			else:
				f_多物体拷贝(物体, 集合, 拷贝数量, self.m_是否实例拷贝, self.m_是否拷贝材质)
			#print('f_多物体拷贝 = ', 集合, 拷贝数量, len(物体))
			#f_多物体拷贝(物体, 集合, 拷贝数量, self.m_是否实例拷贝, self.m_是否拷贝材质)

		新物体 = []
		for obj in 集合.objects:
			新物体.append((list(obj.name), obj.m_物体ID, obj))
		engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(新物体))
		#self.outputs['物体集'].f_setData(新物体)
		return


	def f_release(self):
		集合 = bl_集合物体处理.f_get集合(name='__物体拷贝集合_' + self.name)
		if 集合 :
			for obj in 集合.objects:
				集合.objects.unlink(obj)
				bpy.data.objects.remove(obj)
			bpy.data.collections.remove(集合)
		#print('******************delete ', self.name, 集合)
		super(C_拷贝物体节点, self).f_release()



class C_NODE_MENU_拷贝物体(bpy.types.Operator):
	bl_idname = 'node.global_node_copy_obj'
	bl_label = '物体拷贝'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_拷贝物体节点', use_transform=True)
		return {'FINISHED'}











classes = (
	C_拷贝物体节点,
	C_NODE_MENU_拷贝物体,

)


def register():
	for c in classes:
		bpy.utils.register_class(c)
		
def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)




